Self-Hosted LLM-Infrastruktur
Self-Hosted LLM-Infrastruktur: Implementierung mit LiteLLM, Ollama und Caddy
Einleitung
Die Abhängigkeit von externen LLM-APIs wie OpenAI, Anthropic oder Google birgt Herausforderungen: hohe Kosten, Datenschutzbedenken und Vendor Lock-in. In diesem Beitrag zeige ich, wie wir eine vollständige self-hosted LLM-Infrastruktur aufgebaut haben, die OpenAI-kompatibel ist und dabei vollständige Kontrolle über Daten und Kosten bietet.
- OpenAI-kompatible API mit mehreren LLM-Modellen (Llama 3.1, Mistral, Qwen, etc.)
- GPU-beschleunigte Inferenz mit NVIDIA RTX 4070 Ti (30-50 tokens/sec)
- Automatisches HTTPS mit Let's Encrypt
- Enterprise-grade Monitoring (Prometheus + Grafana)
- Produktionsreife Hochverfügbarkeit
- ~95% Kostenersparnis gegenüber Cloud-LLM-APIs
Architektur-Übersicht
Unsere Infrastruktur basiert auf vier Hauptkomponenten:
┌─────────────────────────────────────────────────┐
│ Internet │
└────────────────────┬────────────────────────────┘
│
▼
┌────────────────┐
│ Caddy Proxy │ (Ports 80, 443, 4080, 4000)
│ Auto-HTTPS │
└────────┬───────┘
│
▼
┌────────────────┐
│ LiteLLM │ (Port 4000)
│ API Gateway │ OpenAI-Compatible
└────────┬───────┘
│
▼
┌────────────────┐
│ Ollama │ (Port 11434)
│ LLM Runtime │ GPU-Accelerated
└────────┬───────┘
│
▼
┌────────────────┐
│ NVIDIA GPU │ RTX 4070 Ti (12GB VRAM)
└────────────────┘
Komponenten
1. Ollama - Der LLM-Runtime
Ollama ist das Herzstück unserer Infrastruktur. Es lädt und führt die LLM-Modelle mit GPU-Beschleunigung aus.
Warum Ollama?
- Einfache Modellverwaltung (Pull, Run, Remove wie bei Docker)
- Automatische Quantisierung (z.B. Q4_K_M für optimale Performance)
- GPU-Support out of the box
- REST-API
2. LiteLLM - Der API Gateway
LiteLLM fungiert als einheitliche Schnittstelle vor Ollama und macht unsere Infrastruktur OpenAI-kompatibel.
Features:
- OpenAI-kompatible API-Endpunkte
- Load Balancing über mehrere Modelle
- Rate Limiting und Budget Management
- Request/Response Logging
- Fallback-Strategien
3. Caddy - Reverse Proxy & HTTPS
Caddy übernimmt die HTTPS-Terminierung und Routing.
Vorteile:
- Automatisches HTTPS mit Let's Encrypt
- Zero-Config für die meisten Szenarien
- HTTP/2 und HTTP/3 Support
- Einfache Konfiguration (Caddyfile)
Installation & Setup
Schritt 1: Ollama mit NVIDIA GPU
# Docker Compose für Ollama
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
environment:
- OLLAMA_HOST=0.0.0.0
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: unless-stopped
volumes:
ollama_data:
Nach dem Start können Sie Modelle herunterladen:
# Llama 3.1 8B
docker exec ollama ollama pull llama3.1:8b
# Mistral 7B
docker exec ollama ollama pull mistral:7b
# Qwen 14B
docker exec ollama ollama pull qwen:14b
Schritt 2: LiteLLM
services:
litellm:
image: ghcr.io/berriai/litellm:main-latest
container_name: litellm
ports:
- "4000:4000"
volumes:
- ./litellm-config.yaml:/app/config.yaml
environment:
- LITELLM_MASTER_KEY=sk-your-master-key
- DATABASE_URL=sqlite:///data/litellm.db
command: ["--config", "/app/config.yaml", "--port", "4000"]
depends_on:
- ollama
restart: unless-stopped
LiteLLM Konfiguration (litellm-config.yaml)
model_list:
- model_name: llama-3.1-8b
litellm_params:
model: ollama/llama3.1:8b
api_base: http://ollama:11434
- model_name: mistral-7b
litellm_params:
model: ollama/mistral:7b
api_base: http://ollama:11434
- model_name: qwen-14b
litellm_params:
model: ollama/qwen:14b
api_base: http://ollama:11434
general_settings:
master_key: sk-your-master-key
max_parallel_requests: 10
database_url: sqlite:///data/litellm.db
Schritt 3: Caddy Reverse Proxy
services:
caddy:
image: caddy:latest
container_name: caddy
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
restart: unless-stopped
volumes:
caddy_data:
caddy_config:
Caddyfile
llm.matzka.cloud {
reverse_proxy litellm:4000
}
ollama.matzka.cloud {
reverse_proxy ollama:11434
}
Performance & Benchmarks
| Modell | Parameter | VRAM | Tokens/Sek | Latenz (First Token) |
|---|---|---|---|---|
| Llama 3.1 8B | 8B | ~5 GB | 40-50 | ~200ms |
| Mistral 7B | 7B | ~4.5 GB | 45-55 | ~180ms |
| Qwen 14B | 14B | ~9 GB | 25-35 | ~300ms |
NVIDIA RTX 4070 Ti (12GB VRAM), AMD Ryzen 9 5900X, 64GB RAM
API-Verwendung
OpenAI-Kompatibel
# Mit OpenAI Python SDK
from openai import OpenAI
client = OpenAI(
base_url="https://llm.matzka.cloud/v1",
api_key="sk-your-master-key"
)
response = client.chat.completions.create(
model="llama-3.1-8b",
messages=[
{"role": "user", "content": "Erkläre Docker in einfachen Worten"}
]
)
print(response.choices[0].message.content)
cURL
curl https://llm.matzka.cloud/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-master-key" \
-d '{
"model": "llama-3.1-8b",
"messages": [
{"role": "user", "content": "Was ist Kubernetes?"}
]
}'
Monitoring & Observability
Wir überwachen unsere LLM-Infrastruktur mit Prometheus und Grafana:
- GPU-Metriken: Auslastung, VRAM, Temperatur
- Request-Metriken: Latenz, Throughput, Fehlerrate
- Modell-Metriken: Tokens/Sek, Active Models
- System-Metriken: CPU, RAM, Disk I/O
Kosten-Vergleich
| Provider | Modell | Input (1M Tokens) | Output (1M Tokens) |
|---|---|---|---|
| OpenAI | GPT-4o | $2.50 | $10.00 |
| Anthropic | Claude 3.5 Sonnet | $3.00 | $15.00 |
| Self-Hosted | Llama 3.1 8B | ~$0.10 | ~$0.10 |
Bei 10M Tokens/Monat: ~$120/Monat → ~$2/Monat = 98% Kostenersparnis
Best Practices
1. Modell-Auswahl
- 7-8B Modelle: Für die meisten Aufgaben ausreichend
- 13-14B Modelle: Für komplexere Reasoning-Tasks
- Quantisierung: Q4_K_M bietet beste Balance (Performance/Qualität)
2. Rate Limiting
Setzen Sie Request-Limits um GPU-Überlastung zu vermeiden:
general_settings:
max_parallel_requests: 5
rpm: 60 # Requests per minute
3. Model Caching
Halten Sie häufig genutzte Modelle im VRAM:
# Preload models
docker exec ollama ollama run llama3.1:8b ""
4. Backup & Recovery
Sichern Sie regelmäßig Ihre Konfigurationen:
# Backup Ollama Models
docker run --rm -v ollama_data:/data -v $(pwd):/backup \
alpine tar czf /backup/ollama-models.tar.gz /data
Troubleshooting
Problem: Out of Memory (OOM)
- Verwenden Sie kleinere Modelle (7B statt 13B)
- Nutzen Sie höhere Quantisierung (Q4 statt Q8)
- Reduzieren Sie
max_parallel_requests
Problem: Langsame Inferenz
- Prüfen Sie GPU-Auslastung:
nvidia-smi - Stellen Sie sicher, dass GPU genutzt wird (nicht CPU)
- Verwenden Sie optimierte Quantisierung (Q4_K_M)
Problem: HTTPS-Zertifikat funktioniert nicht
- DNS-Records prüfen (A-Record muss auf Server-IP zeigen)
- Port 80/443 muss erreichbar sein
- Caddy-Logs prüfen:
docker logs caddy
Lessons Learned
- VRAM ist der Flaschenhals: 12GB reichen für 2-3 kleinere Modelle gleichzeitig
- Quantisierung ist entscheidend: Q4_K_M bietet beste Balance
- LiteLLM ist production-ready: Stabile API mit gutem Monitoring
- Caddy vereinfacht HTTPS: Zero-Config für Let's Encrypt
- Lokale LLMs sind schnell genug: 40+ tokens/sec für die meisten Use Cases
Fazit
Eine self-hosted LLM-Infrastruktur ist heute absolut realistisch und bietet massive Vorteile:
- ✅ Kosteneinsparung: 95%+ gegenüber Cloud-APIs
- ✅ Datenschutz: Alle Daten bleiben intern
- ✅ Keine Vendor Lock-in: OpenAI-kompatible API
- ✅ Volle Kontrolle: Modellwahl, Rate Limits, Logging
- ✅ Performance: 40+ tokens/sec mit Consumer-GPU
Mit einer RTX 4070 Ti und den richtigen Tools können Sie eine production-grade LLM-Infrastruktur aufbauen, die 95% günstiger ist als Cloud-APIs und dabei volle Kontrolle über Ihre Daten bietet.
Technologie-Stack
- LLM Runtime: Ollama
- API Gateway: LiteLLM
- Reverse Proxy: Caddy
- Container: Docker & Docker Compose
- GPU: NVIDIA RTX 4070 Ti (12GB VRAM)
- Monitoring: Prometheus + Grafana
- HTTPS: Let's Encrypt (via Caddy)
Code & Dokumentation
📂 github.com/reinmatz/matzka-cloud